home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / TC2PROM.ARJ / ROMIZE.C < prev    next >
Text File  |  1991-05-01  |  8KB  |  322 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <dos.h>
  4.  
  5. #define sym_tab_size 500
  6. #define ntokens 20         /* max tokens per line */
  7. #define tokensep "\t :+-,[]\n"
  8.  
  9. #define true 1
  10. #define false 0
  11. #define mybuffsize 4096
  12.  
  13. /* this program can be compiled in small model */
  14.  
  15. /* Schema for converting Turbo C assembly output to ROMable code:
  16.  
  17.  Pass 1: build a table of symbols in _DATA segment
  18.  
  19.   (omit "_TEXT" and "_BSS" segment symbols)
  20.  
  21.  Pass 2:
  22.      a. Change the "DGROUP" group command to just "_BSS"
  23.      b. Add a "CGROUP" with _TEXT,_DATA
  24.      c. Change the assume to "assume cs:CGROUP,ds:DGROUP"
  25.  
  26.      d: change group reference for any symbol in "_DATA" segment
  27.            from "DGROUP" to "CGROUP"
  28.            add a "CGROUP:" reference if none exists
  29.  
  30.      e: change associated ds reference to cs
  31.          1. a "mov" before
  32.          2. a "push  ds" before or after
  33.  
  34. 1/16/89  Updated by the author for Turbo C 2.0
  35.  
  36.    */
  37.  
  38.   struct sym_table_entry {
  39.     char symbol[32];
  40.   };
  41.  
  42.   struct sym_table_entry sym_table[sym_tab_size];
  43.  
  44.   int no_symbols;
  45.  
  46.   char ibuff[mybuffsize];
  47.   char obuff[mybuffsize];
  48.  
  49.   FILE *asmsource;
  50.   FILE *output;
  51.  
  52.  
  53.   char prev_line[255];
  54.   char next_line[255];
  55.   char curr_line[255];
  56.  
  57.   /* insert text *c at *r in a string *p
  58.      assumes there is enough room to do the insertion */
  59.  
  60. void strins(char *p,char *r,char *c)
  61. {
  62.   int i,m,n;
  63.   char work[255];
  64.   m = r - p;           /* # chars in 1st part of *p */
  65.   strcpy(work,p);      /* work = all of *p */
  66.   work[m] = 0;         /* trunc to length up to *r */
  67.   strcat(work,c);      /* append *c */
  68.   strcat(work,r);      /* append rest of *p */
  69.   strcpy(p,work);      /* move back to p *p */
  70.   /* printf("strins --%s",p); */
  71. }
  72.  
  73. struct sym_table_entry *search_sym(char *sym)
  74. {
  75.   struct sym_table_entry *p;
  76.   int i;
  77.  
  78.   p = sym_table; i = 0;
  79.   while ((i < no_symbols) && strcmp((char*)p,sym)) {
  80.     p++;
  81.     i++;
  82.   }
  83.   if (i == no_symbols) return (NULL);
  84.   else return (p);
  85. }
  86.  
  87.   /* search the line for an occurrence of any symbol in table */
  88.  
  89. char *sym_in_line(char *theline)
  90. {
  91.   int i;
  92.   char *p;
  93.   i = 0;
  94.   while ((i < no_symbols) && (!(p = strstr(theline,sym_table[i].symbol))))
  95.     i++;
  96.   if (i < no_symbols) return (p);
  97.   else return (NULL);
  98. }
  99.  
  100. void list_symbols(void)
  101. {
  102.   int i;
  103.   for (i = 0; i < no_symbols; i++)
  104.     printf("%s\n",sym_table[i].symbol);
  105. }
  106.  
  107. void add_symbol(char *sym)
  108. {
  109.   /* printf("%s symbol to add\n",sym); */
  110.   strcpy(sym_table[no_symbols++].symbol,sym);
  111. }
  112.  
  113. /* Pass1 -- Read through the text and accumulate a table of
  114.   symbols in the _DATA segment -- returns # lines input */
  115.  
  116. int pass1(void)
  117. {
  118.   int i;
  119.   int linect;
  120.   char *s[ntokens];
  121.   char dataseg;   /* boolean == in _DATA segment */
  122.   char cursegname[20];
  123.  
  124.   no_symbols = 0;
  125.   linect = 0;
  126.  
  127.   cursegname[0] = 0;  /* no current segment */
  128.   dataseg = false;
  129.  
  130.   while (!feof(asmsource)) {
  131.     fgets(curr_line,sizeof(curr_line),asmsource);
  132.     linect++;
  133.  
  134.     /* printf("%s",curr_line); */
  135.     i = 0;
  136.     s[i] = strtok(curr_line,tokensep);
  137.     while (s[i]) {
  138.       /* printf("%s||",s[i]); */
  139.       s[++i] = strtok(NULL,tokensep);
  140.     }
  141.     if (!i) continue;   /* 0 - length line */
  142.     if (s[0] == ";") continue;  /* comment, ignore */
  143.     /* printf(" %d tokens\n",i); */
  144.     if (i > 1) {
  145.       if (!strcmp(s[1],"segment")) {
  146.         if (!strcmp(s[0],"_DATA")) {
  147.           dataseg = true;
  148.           /* printf("Begin _DATA segment \n"); */
  149.         }
  150.         strcpy(cursegname,s[0]);
  151.         continue;
  152.       }
  153.     }
  154.     if (!strcmp(s[1],"ends") && !strcmp(s[0],"_DATA")) {
  155.       dataseg = false;
  156.       /* printf("End _DATA segment \n"); */
  157.       cursegname[0] = 0;   /* no current segment */
  158.       continue;
  159.     }
  160.     if (dataseg && !strcmp(s[1],"label")) {
  161.       add_symbol(s[0]);
  162.       continue;
  163.     }
  164.       /* extrn not in any segment */
  165.     if (!strcmp(s[0],"extrn") && !cursegname[0]) {
  166.       add_symbol(s[1]);
  167.       continue;
  168.     }
  169.  
  170.   }  /* while not eof */
  171.   list_symbols();
  172.   return (linect);
  173. }
  174.  
  175. /* Pass 2 processing - see above -- returns # lines output */
  176.  
  177. int pass2(void)
  178. {
  179.   int   i,j, linect;
  180.   struct sym_table_entry *s;
  181.   char *t[ntokens];
  182.   char *tt[ntokens];
  183.   char *r,*u;
  184.  
  185.   char linebuff[255];
  186.   char linebuff2[255];
  187.  
  188.   prev_line[0] = 0;   /* clear prev_line */
  189.  
  190.   /* Fill the pipeline */
  191.   fgets(prev_line,sizeof(prev_line),asmsource);
  192.   fgets(curr_line,sizeof(curr_line),asmsource);
  193.   fgets(next_line,sizeof(next_line),asmsource);
  194.   linect = 0;
  195.  
  196.   do {
  197.     /* printf("%s",curr_line); */
  198.     i = 0;  /* get tokens */
  199.     strcpy(linebuff,curr_line);
  200.     t[i] = strtok(linebuff,tokensep);
  201.     while (t[i]) {
  202.       /* printf("%t||",t[i]); */
  203.       t[++i] = strtok(NULL,tokensep);
  204.     }
  205.     if (!strcmp(t[0],"assume")) {
  206.       /* substutite new assume statement */
  207.       strcpy(curr_line,"\tassume\tcs:CGROUP,ds:DGROUP\n");
  208.  
  209.       /* printf("assume  cs:CGROUP,ds:DGROUP\n"); */
  210.     }
  211.     else if (!strcmp(t[1],"group")) {
  212.       strcpy(curr_line,"DGROUP\tgroup\t_BSS\n");
  213.      /* insert a CGROUP line */
  214.       fputs(prev_line,output);
  215.       linect++;
  216.       strcpy(prev_line,curr_line);
  217.       strcpy(curr_line,"CGROUP\tgroup\t_TEXT,_DATA\n");
  218.       linect++;
  219.  
  220.       /* printf("DGROUP\tgroup\t_BSS\n");
  221.       printf("CGROUP\tgroup\t_TEXT,_DATA\n"); */
  222.  
  223.     }
  224.     else if (!strcmp(t[0],"extrn"));
  225.     else if (!strcmp(t[0],"public"));
  226.     else if (!strcmp(t[1],"label"));
  227.  
  228.     else if (r = sym_in_line(curr_line)) {  /* symbol found in line */
  229.       if (u = strstr(curr_line,"DGROUP:")) {   /* "DGROUP" found */
  230.         *u = 'C';   /* change to CGROUP: */
  231.  
  232. /* following three lines added for v 2.0.  A "dd" statement has
  233.    two "DGROUP" references in it */
  234.  
  235.         if (!strcmp(t[0],"dd") && (u = strstr(curr_line,"DGROUP:"))) {
  236.           *u = 'C';   /* change to CGROUP: */
  237.         }
  238.       }
  239.       else {   /* no group found, insert "CGROUP: in line before symbol */
  240.         strins(curr_line,r,"CGROUP:");
  241.       }
  242.  
  243.           /* now check for previous line with ds reference */
  244.           /* tokenize previous line */
  245.  
  246.       strcpy(linebuff,prev_line);
  247.       i = 0;
  248.       tt[i] = strtok(linebuff,tokensep);
  249.       while (tt[i]) tt[++i] = strtok(NULL,tokensep);
  250.       /*  see if "ds" present */
  251.       i = 0;
  252.       while (tt[i] && strcmp(tt[i],"ds")) i++;
  253.       if (tt[i]) {  /* "ds" found, change to "cs" */
  254.         *(prev_line + (tt[i] - linebuff)) = 'c';
  255.         /* printf("Previous line %s",prev_line); */
  256.       }
  257.       else {  /* not on previous line, check next line */
  258.         strcpy(linebuff,next_line);
  259.         i = 0;
  260.         tt[i] = strtok(linebuff,tokensep);
  261.         while (tt[i]) tt[++i] = strtok(NULL,tokensep);
  262.         i = 0;
  263.         while (tt[i] && strcmp(tt[i],"ds")) i++;
  264.         if (tt[i]) {  /* ds found in next line */
  265.           *(next_line + (tt[i] - linebuff)) = 'c';
  266.           /* printf("Following line %s",next_line); */
  267.         }
  268.  
  269.       }
  270.  
  271.     } /* if symbol found in line */
  272.  
  273.     fputs(prev_line,output);
  274.     linect++;
  275.     strcpy(prev_line,curr_line);
  276.     strcpy(curr_line,next_line);
  277.     fgets(next_line,sizeof(next_line),asmsource);
  278.   } while (!feof(asmsource));
  279.   /* empty the pipeline */
  280.   fputs(prev_line,output);
  281.   fputs(curr_line,output);
  282.   linect += 2;
  283.   return (linect);
  284. }
  285.  
  286.  
  287. int main(int argc, char *argv[])
  288. {
  289.   int l;
  290.  
  291.   if (argc < 3) {
  292.     printf("Usage:  romize input.asm output.asm \n");
  293.     return (1);
  294.   }
  295.  
  296.   asmsource = fopen(argv[1],"rt");
  297.   if (!asmsource) {
  298.     printf("Trouble opening input file\n");
  299.     return(1);
  300.   }
  301.   setvbuf(asmsource,ibuff,_IOFBF,mybuffsize);
  302.   l = pass1();
  303.   fclose(asmsource);
  304.   printf("%d Lines input\n",l);
  305.  
  306.   asmsource = fopen(argv[1],"rt");
  307.   setvbuf(asmsource,ibuff,_IOFBF,mybuffsize);
  308.   output = fopen(argv[2],"wt");
  309.   if (!output) {
  310.     printf("Trouble opening output\n");
  311.     fclose(asmsource);
  312.     return(1);
  313.   }
  314.   setvbuf(output,obuff,_IOFBF,mybuffsize);
  315.  
  316.   l = pass2();
  317.   fclose(asmsource);
  318.  
  319.   fclose(output);
  320.   printf("%d Lines output\n",l);
  321.   return(0);
  322. }